//
//  TCPManager.m
//  CoolFlow
//
//  Created by admin on 16/3/14.
//  Copyright © 2016年 admin. All rights reserved.
//

#import "TCPManager.h"
#import "AsyncSocket.h"

#define SOCKET_TCP_HEAD_TAG 1 //Head tag
#define SOCKET_TCP_BODY_TAG 2 //Body tag

@interface TCPManager()
@property (nonatomic, strong) AsyncSocket   *mySocket;
@property (nonatomic, strong) NSMutableData *recvData;
@property (nonatomic, strong) NSData  *sendDicParameters;
@property (nonatomic, copy) void (^ReceiveDataPackCompletedBlock) (SkyTcpCmdDataPack *decodeTcpDataPack);
@end

@implementation TCPManager
#pragma mark - Public
//instance
+ (TCPManager *)shareInstance {
    static dispatch_once_t  onceToken;
    static TCPManager * sSharedInstance;
    
    dispatch_once(&onceToken, ^{
        sSharedInstance = [[TCPManager alloc] init];
    });
    return sSharedInstance;
}

- (void)getKIFrom:(NSString *) strIP withPort:(UInt16) nPort withData:(NSData *) dicData {
    self.sendDicParameters = dicData;
    [self connect:strIP withPort:nPort];
}
/**
 *  get KI or release ki
 *
 *  @param strIP     服务器地址
 *  @param nPort     端号
 *  @param dataPack  发送数据
 *  @param completed 取到ki数据的回调
 */
- (void)getKIFrom:(NSString *) strIP withPort:(UInt16) nPort skyTcpCmdData:(SkyTcpCmdDataPack *) dataPack dataPackReceiveCompleted:(void(^)(SkyTcpCmdDataPack *decodeTcpDataPack))completed{

    [self getKIFrom:strIP withPort:nPort withData:[dataPack encodeDataPack]];
    self.ReceiveDataPackCompletedBlock=completed;
}

#pragma mark - Private
//connect
- (void)connect:(NSString *) strIP withPort:(UInt16) nPort {
    [self disConnect];
    
    if ([strIP length] == 0 || nPort == 0) {
        NSLog(@"IP/port is empty");
        return;
    }
    
    self.recvData = [[NSMutableData alloc] init];
    
    self.mySocket = [[AsyncSocket alloc] initWithDelegate:self];
    
    NSError *error = nil;
    if ([self.mySocket connectToHost:strIP onPort:nPort withTimeout:10.0f error:&error]) {
        NSLog(@"tcp connect success : %@:%d", strIP, nPort);
    } else {
        NSLog(@"tcp connect failed : %@:%d,error is %@", strIP, nPort, error);
    }
}

//disconnect
- (void)disConnect {
    if (self.mySocket) {
        if ([self.mySocket isConnected]) {
            [self.mySocket disconnect];
        }
        self.mySocket = nil;
    }
}

//senddata
- (void)sendData:(NSData *) data {
    if (self.mySocket && [self.mySocket isConnected]) {
        [self.mySocket writeData:data withTimeout:-1 tag:1];
    }
}

//parseData
- (void)parseData:(NSMutableData *)data {
    SkyTcpCmdDataPack *mod=[SkyTcpCmdDataPack decodeWithDataPack:self.recvData];
    if (self.ReceiveDataPackCompletedBlock) {
        self.ReceiveDataPackCompletedBlock(mod);
    }
    self.ReceiveDataPackCompletedBlock=nil;
    //[self disConnect];
}

#pragma mark - AsyncSocketDelegate
- (BOOL)onSocketWillConnect:(AsyncSocket *)sock {
    NSLog(@"%s", __FUNCTION__);
    return YES;
}

- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port {
    NSLog(@"%s", __FUNCTION__);
    //首先读取头，4个字节
    [self.mySocket readDataToLength:2 withTimeout:-1 tag:SOCKET_TCP_HEAD_TAG];
    //发送数据
    [self sendData:self.sendDicParameters];
}

- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err {
    NSLog(@"%s", __FUNCTION__);
    NSLog(@"error  = %@", err);
    
    //连接失败数据处理返回
    [self parseData:nil];
}

- (void)onSocketDidDisconnect:(AsyncSocket *)sock {
    NSLog(@"%s", __FUNCTION__);
    NSLog(@"tcp已断开连接了");
    
    
}

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    NSLog(@"%s", __FUNCTION__);
    if (SOCKET_TCP_BODY_TAG == tag) {
        [self.recvData appendData:data];
        [self parseData:self.recvData];
        //首先读取头，4个字节
        [self.mySocket readDataToLength:2 withTimeout:-1 tag:SOCKET_TCP_HEAD_TAG];
    } else if (SOCKET_TCP_HEAD_TAG == tag) {
        short nLen = 0;
        [data getBytes:(void *)&nLen length:2];
        nLen = ntohs(nLen);
        NSLog(@"call body data length = %d", nLen);
        NSInteger nLeftDataLen = nLen;
        if (nLeftDataLen > 0) {
            [self.recvData setLength:0];
            [sock readDataToLength:nLeftDataLen withTimeout:-1 tag:SOCKET_TCP_BODY_TAG];
        } else if (nLeftDataLen == 0) {
            [self.recvData setLength:0];
            [sock readDataToLength:2 withTimeout:-1 tag:SOCKET_TCP_HEAD_TAG];
        }
    } else {
        NSLog(@"onSocket tag (%ld) Error!", tag);
    }
}

- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag {
    NSLog(@"%s", __FUNCTION__);
}

@end
